package com.dragon.utilslibrary.tools;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

/**
 * 时间转换工具类，设计时间格式化、UTC与用户时间相互转换等函数成员；还包含计算自然周的始末时间。
 * 另外对SimpleDateFormat进行说明。SimpleDateFormat默认时区为当前手机设置时区，
 * 如果增加setTimeZone(TimeZone.getTimeZone("UTC"))的操作，会将时间进行UTC时间转换。
 *
 * @author Allow.xuweibin
 */
public class DateConvertUtils {
    public int mStartTime;
    public int mEndTime;

    /**
     * 获取当前时间戳，精度为秒，毫秒所占尾三位均置零
     *
     * @return
     */
    public static long getCurrentTimeMillis() {
        return 1000 * (System.currentTimeMillis() / 1000);
    }

    /**
     * 过去当前用户时间
     *
     * @param format 时间格式：yyyMMdd 或 yyyy/MM/dd
     * @return
     */
    public static String getDateToString(String format) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    /**
     * UTC时间转成服务器格式时间
     *
     * @param time
     * @return
     */
    public static String convertTimeToServiceType(long time) {
        return convertTimeToString(time, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * UTC时间转成date类型，可以单独取出年，日，月
     *
     * @param time
     * @return
     */
    public static Date getDate(long time) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date d = null;
        try {
            d = sf.parse(convertTimeToServiceType(time));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return d;
    }

    /**
     * 根据UTC时间获取当月的天数
     *
     * @param time
     * @return
     */
    public static int getMonthDay(int time) {
        Date dTime = DateConvertUtils.getDate(time);
        int year = dTime.getYear();
        int month = dTime.getMonth();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        int monthDay = calendar.get(Calendar.MONDAY);

        return 1;
    }

    /**
     * UTC时间转化为UTC字符串
     *
     * @param time   ：要被格式化的long型
     * @param format ：要格式化个数据格式 ，如：yyyy-MM-dd HH:mm:ss/yyyy-MM-dd/MM-dd等等。。。
     * @return
     */
    public static String convertTimeToString(long time, String format) {
        SimpleDateFormat sDateFormat = new SimpleDateFormat(format);
        sDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        String dateString = sDateFormat.format(new Date(time));
        return dateString;
    }

    /**
     * 数据库时间戳转字符串
     *
     * @param time
     * @param format
     * @return
     */
    public static String convertTimeToStringT(long time, String format) {
        SimpleDateFormat mDateFormat = new SimpleDateFormat(format);
        String dateString = mDateFormat.format(time);
        return dateString;
    }

    /**
     * 数据库时间戳转字符串
     *
     * @param time
     * @param format
     * @return
     */
    public static String convertTimeToStringT2(long time, String format) {
        SimpleDateFormat mDateFormat = new SimpleDateFormat(format, Locale.ENGLISH);
        String dateString = mDateFormat.format(time);
        return dateString;
    }

    /**
     * 字符串时间转为数据库时间戳
     *
     * @param timeStr
     * @param format
     * @return
     */
    public static long convertStringToTimeT(String timeStr, String format) {
        SimpleDateFormat mDateFormat = new SimpleDateFormat(format);
        long time = 0;
        try {
            Date date = mDateFormat.parse(timeStr);
            time = date.getTime();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return time;
    }

    /**
     * 字符串时间转为数据库时间戳
     *
     * @param timeStr
     * @param format
     * @return
     */
    public static long convertStringToTimeT2(String timeStr, String format) {
        SimpleDateFormat mDateFormat = new SimpleDateFormat(format, Locale.ENGLISH);
        long time = 0;
        try {
            Date date = mDateFormat.parse(timeStr);
            time = date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time;
    }

    /**
     * 服务器时间格式转成时间戳 yyyy-MM-dd HH:mm:ss 转成 long 型
     *
     * @param date ： 服务器时间格式字符串
     * @return long型时间戳
     */
    public static long convertServiceTypeToMill(String date) {
        return convertStringToMill(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * UTC字符串转化为UTC
     *
     * @param date   ： 要被转换的格式化时间字符串
     * @param format ： date对应的格式化格式
     * @return
     */
    public static long convertStringToMill(String date, String format) {
        long ret = 0;
        SimpleDateFormat sDateFormat = new SimpleDateFormat(format);
        sDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        try {
            Date time = sDateFormat.parse(date);
            ret = time.getTime();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * 把用户时区时间转化成标准时间，字符串转字符串
     *
     * @param date   ：用户时间字符串
     * @param format ：需要格式化的UTC字符串时间格式
     * @return 返回UTC字符串
     */
    public static String convertUserToUTC(String date, String format) {
        long offset = TimeZone.getDefault().getRawOffset();
        SimpleDateFormat sDateFormat = new SimpleDateFormat(format);
        sDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date time;
        long ret = 0;
        try {
            time = sDateFormat.parse(date);
            ret = time.getTime() - offset;
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return sDateFormat.format(ret);
    }

    /**
     * 根据标准时间戳转化为用户时间
     *
     * @param time   ：长整形UTC时间转成用户指定时间格式字符串
     * @param format ：用户时间格式
     * @return 返回指定格式化的用户时间
     */
    public static String convertUTCToUser(long time, String format) {
        SimpleDateFormat sDateFormat = new SimpleDateFormat(format);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        String dateString = sDateFormat.format(calendar.getTime());

        return dateString;
    }

    public static long convertUTCMillToUserMill(long time) {
        TimeZone timeZone = Calendar.getInstance().getTimeZone();
        return time + timeZone.getRawOffset();
    }

    public static long convertUserMillToUTCMill(long time) {
        TimeZone timeZone = Calendar.getInstance().getTimeZone();
        return time - timeZone.getRawOffset();
    }

    /**
     * 把用户时间转化为UTC时间戳
     *
     * @param date
     * @param format
     * @return
     */
    public static long convertUserToUTCMill(String date, String format) {
        SimpleDateFormat sDateFormat = new SimpleDateFormat(format);// 默认已用户时间看待进行转换
        Date time;
        long ret = 0;
        try {
            time = sDateFormat.parse(date);
            ret = time.getTime();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ret;
    }

    public static final long DAY_OF_MILL = 24 * 60 * 60 * 1000;
    public static final long WEEK_OF_MILL = 7 * DAY_OF_MILL;

    /**
     * 根据实际格式进行赋予
     *
     * @param date 时间如 20141213
     * @param form 格式化 yyyyMMdd
     * @return is starting at 0 up to FIELD_COUNT int
     */
    public static int getDayOfWeek(int date, String form) {
        Calendar cal = Calendar.getInstance();
        Date currentDate = null;
        SimpleDateFormat sDateFormat = new SimpleDateFormat(form);
        try {
            currentDate = sDateFormat.parse(date + "");
            cal.setTimeInMillis(currentDate.getTime());

        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return cal.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 获取当前周的日期开始和结束
     *
     * @param utc 该时间有用户时间 yyyyMMdd替换成utc即可。
     * @return 返回时间格式 mstartTime 20140901
     */
    public static DateConvertUtils getTimeSectionOfWeek(long utc) {
        DateConvertUtils section = new DateConvertUtils();
        long offset = TimeZone.getDefault().getRawOffset();
        long userTime = utc + offset;
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(userTime);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK) - cal.getFirstDayOfWeek(); //
        cal.setTimeInMillis(userTime - dayofweek * DAY_OF_MILL);
        section.mStartTime = cal.get(Calendar.YEAR) * 10000 + (cal.get(Calendar.MONTH) + 1) * 100
                + cal.get(Calendar.DATE);
        long endTemptime = userTime + (7 - dayofweek - 1) * DAY_OF_MILL;
        cal.setTimeInMillis(endTemptime);
        section.mEndTime = cal.get(Calendar.YEAR) * 10000 + (cal.get(Calendar.MONTH) + 1) * 100
                + cal.get(Calendar.DATE);

        return section;
    }

    public static long getNextWeek(long utc) {
        return utc + WEEK_OF_MILL;
    }

    public static long getPreWeek(long utc) {
        return utc - WEEK_OF_MILL;
    }

    /**
     * 获取当前月的日期开始和结束
     *
     * @param time
     * @return
     */
    public static ArrayList<DateConvertUtils> getTimeSectionOfMonth(int time) {
        ArrayList<DateConvertUtils> weekMonthArrayList = new ArrayList<DateConvertUtils>();
        int weekOfMonth = 0;
        // DataSyncUtil section = new DataSyncUtil();
        // 返回这个月的天数 YYYYMM
        Date date = null;
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMdd");
        try {
            date = sDateFormat.parse(time + "");
            cal.setTimeInMillis(date.getTime());

        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        int dayofmonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

        int firstDay = time / 100 * 100 + 1;
        int endDay = time / 100 * 100 + dayofmonth;
        int curMonthMaxendDay = endDay;

        cal.set(time / 10000, time / 100 % 100 - 1, 1);
        int firstaddDay = cal.get(Calendar.DAY_OF_WEEK) - 1;

        SimpleDateFormat sDateFormat1 = new SimpleDateFormat("yyyyMMdd");
        if (firstaddDay > 0) {
            weekOfMonth++;
            cal.add(Calendar.DATE, -firstaddDay);
            try {
                firstDay = Integer.parseInt(sDateFormat1.format(cal.getTime()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            cal.add(Calendar.DATE, 6);
            try {
                endDay = Integer.parseInt(sDateFormat1.format(cal.getTime()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            DateConvertUtils section = new DateConvertUtils();
            section.mStartTime = firstDay;
            section.mEndTime = endDay;

            weekMonthArrayList.add(section);
        }
        for (int i = 0; i < 4; i++) {
            DateConvertUtils section = new DateConvertUtils();
            // weekOfMonth++;
            if (weekOfMonth == 0) {
                section.mStartTime = firstDay;
            } else {
                section.mStartTime = weekMonthArrayList.get(weekOfMonth - 1).mEndTime + 1;
            }
            section.mEndTime = section.mStartTime + 6;
            if (section.mEndTime > curMonthMaxendDay) {
                break;
            }
            weekMonthArrayList.add(section);
            weekOfMonth++;
        }

        cal.set(time / 10000, time / 100 % 100 - 1, dayofmonth);
        int endaddDay = 7 - cal.get(Calendar.DAY_OF_WEEK);
        if (endaddDay > 0) {
            weekOfMonth++;
            cal.add(Calendar.DATE, endaddDay);
            try {
                endDay = Integer.parseInt(sDateFormat1.format(cal.getTime()));
            } catch (Exception e) {
                e.printStackTrace();
            }

            DateConvertUtils section = new DateConvertUtils();
            section.mStartTime = weekMonthArrayList.get(weekMonthArrayList.size() - 1).mEndTime + 1;
            section.mEndTime = endDay;
            weekMonthArrayList.add(section);
        }

        return weekMonthArrayList;

    }

    /**
     * @param time (YYYYMMDD)
     * @return
     */
    public static int getPreMonth(int time, int num) {

        int year = time / 10000;
        int month = time / 100 % 100;
        int yearsub = (num - month) / 12 + 1;
        if (month - num == 0) {
            year--;
            month = 12;
        } else if (month - num < 0) {
            year -= yearsub;
            month = 12 - (num - month) % 12;
        } else {
            month -= num;
        }

        int date = year * 10000 + month * 100 + 1;
        return date;

    }

    /**
     * @param time (YYYYMMDD)
     * @return
     */
    public static int getNextMonth(int time, int num) {

        int year = time / 10000;
        int month = time / 100 % 100;

        int yearadd = (month + num) / 12;
        if (month + num >= 12) {
            if ((month + num) % 12 == 0) {
                year += (yearadd - 1);
            } else {
                year += yearadd;
            }
            month = (month + num) % 12 == 0 ? 12 : (month + num) % 12;
        } else {
            month += num;
        }

        int date = year * 10000 + month * 100 + 1;
        return date;

    }

    public static String getNextOrPreDay(int date, int num) {
        int year = date / 10000;
        int month = date % 10000 / 100 - 1;
        int day = date % 100;
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, day);
        calendar.add(Calendar.DATE, num);
        String dateString = sDateFormat.format(calendar.getTime());
        return dateString;

    }

    public static int getWeekOfDay(long date) {
        int year = (int) (date / 10000);
        int month = (int) (date % 10000 / 100) - 1;
        int day = (int) (date % 100);
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, day);
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /***
     *判断日期是否为未来日期
     * @param string
     * @return
     */
    public static boolean isNextDay(String string) {
        long userUTC = convertUserToUTCMill(string, "yyyy/MM/dd");//选择的日期00:00:00时的时间戳
        long currentTimeMillis = getCurrentTimeMillis();//获取当前时间的时间戳
        String currentDate = convertUTCToUser(currentTimeMillis, "yyyy/MM/dd");//获取当前天的年月日
        long currentUTC = convertUserToUTCMill(currentDate, "yyyy/MM/dd");//获取当前天00:00:00时的时间戳
        if (userUTC > currentUTC) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 将时间S转为00:00:00格式
     *
     * @param seconds
     * @return
     */
    public static String secondToTime(int seconds) {
        DecimalFormat dfDecimalFormat = new DecimalFormat("00", new DecimalFormatSymbols(Locale.US));
        String hourStr = dfDecimalFormat.format(seconds / 3600);
        String mimuteStr = dfDecimalFormat.format((seconds % 3600) / 60);
        String secondStr = dfDecimalFormat.format(seconds % 60);
        return hourStr + ":" + mimuteStr + ":" + secondStr;
    }

    /**
     * 将年月转为yyyy/MM格式
     *
     * @param year
     * @param month
     * @return
     */
    public static String timeToMonthForYear(int year, int month) {
        DecimalFormat dfDecimalFormat = new DecimalFormat("00", new DecimalFormatSymbols(Locale.US));
        return year + "/" + dfDecimalFormat.format(month);
    }

    public static String getLastMonthOfYear(int year, int month) {
        String lastMonth;
        if (month == 1) {
            lastMonth = (year - 1) + "/" + 12;
        } else {
            lastMonth = year + "/" + (month - 1);
        }
        return lastMonth;
    }

    public static String getNextMonthOfYear(int year, int month) {
        String nextMonth;
        if (month == 12) {
            nextMonth = (year + 1) + "/1";
        } else {
            nextMonth = year + "/" + (month + 1);
        }
        return nextMonth;
    }

    /**
     * 获取当前时间并转化为蓝牙要求的byte数据格式
     *
     * @return
     */
    public static byte[] getTimeData() {
        int year = Calendar.getInstance().get(Calendar.YEAR) - 2000;
        int month = Calendar.getInstance().get(Calendar.MONTH) + 1;
        int day = Calendar.getInstance().get(Calendar.DATE);
        int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        int minute = Calendar.getInstance().get(Calendar.MINUTE);
        int second = Calendar.getInstance().get(Calendar.SECOND);
        byte[] bytes = new byte[6];
        bytes[0] = (byte) day;
        bytes[1] = (byte) month;
        bytes[2] = (byte) year;
        bytes[3] = (byte) hour;
        bytes[4] = (byte) minute;
        bytes[5] = (byte) second;
        return bytes;
    }

    public static String timeToDataFormat(int year, int month, int day, int hour, int minute, int second) {
        DecimalFormat yearDec = new DecimalFormat("0000", new DecimalFormatSymbols(Locale.US));
        DecimalFormat dfDecimalFormat = new DecimalFormat("00", new DecimalFormatSymbols(Locale.US));
        return yearDec.format(year) + "/" + dfDecimalFormat.format(month) + "/" + dfDecimalFormat.format(day) + " " + dfDecimalFormat.format(hour) + ":" + dfDecimalFormat.format(minute) + ":" + dfDecimalFormat.format(second);
    }

    /**
     * 获得某天0点时间 (秒级时间戳)
     *
     * @return
     */
    public static int getTimesmorning(long time) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis((long) time * 1000);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis() / 1000);
    }

    /**
     * 获得某天24点时间 (秒级时间戳)
     *
     * @return
     */
    public static int getTimesnight(long time) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis((long) time * 1000);
        cal.set(Calendar.HOUR_OF_DAY, 24);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis() / 1000);
    }

    /**
     * 此函数非原创，从网上搜索而来，timeZoneOffset原为int类型，为班加罗尔调整成float类型
     * timeZoneOffset表示时区，如中国一般使用东八区，因此timeZoneOffset就是8
     *
     * @param timeZoneOffset
     * @return
     */
    public static String getFormatedDateStringByTimeZoneOffset(Long time, float timeZoneOffset, String strFormat) {
        if (timeZoneOffset > 13 || timeZoneOffset < -12) {
            timeZoneOffset = 0;
        }
        int newTime = (int) (timeZoneOffset * 60 * 60 * 1000);
        TimeZone timeZone;
        String[] ids = TimeZone.getAvailableIDs(newTime);
        if (ids.length == 0) {
            timeZone = TimeZone.getDefault();
        } else {
            timeZone = new SimpleTimeZone(newTime, ids[0]);
        }
        SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
        sdf.setTimeZone(timeZone);
        return sdf.format(new Date(time));
    }

}
